#include <gnome.h>
#include <assert.h>
#include <math.h>
#include <string.h>

#include <gr_graph_fun.h>

#include "client_protocol.h"
#include "stats.h"
#include "monitor.h"

#include "perror_exit.h"

void
SetPathInfo(w3lclient *client, GtkWidget *app, char *username)
{
	char *UserPath;
	char *nl;
	char *tb;
	char *beer;
	int i=0;
	char *datum[4];

	GtkListStore *listStore;
	GtkTreeIter  iter;
	
	beer = UserPath = w3lRequest(client,"user_path(%s)",username);

	listStore = (GtkListStore *)gtk_tree_view_get_model(
			(GtkTreeView *)lookup_widget(app,"treeviewGraph"));
	
	gtk_list_store_clear(listStore);
	
	while((nl = strchr(UserPath,'\n'))) {
		*nl = '\0';
		i=0;
		while((tb = strchr(UserPath,'\t'))) { /* i might ignore a last field ... oops */
			*tb = '\0';
			datum[i++] = UserPath;
			if(*(tb+1) == '\n' || *(tb+1) == '\0')
				break;
			UserPath = tb+1;
		}
		gtk_list_store_append(listStore, &iter);
		gtk_list_store_set(listStore, &iter,
				PATH_COL_URLS, datum[0],
				PATH_COL_MIME, datum[1],
				PATH_COL_CODE, datum[2],
				PATH_COL_URLT, datum[3],
				-1);
		if(*(nl+1) == '\0')
			break;
		UserPath = nl+1;
	}
	free(beer);
}

void updateUserInfo(w3lclient *client,statStorage *data) { 
	char *users = NULL;
	char *lunch;
	char *nl;
	int i;
	char *tmp;
	
	extern monitor monitors[];

	lunch = users = w3lRequest(client,"list_users()");
	
	while((nl = strchr(users,'\n'))) {
		userInfo *ui = NULL;
		
		*nl = '\0';

		if(!(ui = (userInfo *)malloc(sizeof(userInfo))))
			perror_exit("%s:%d ",__FILE__,__LINE__);

		if(!(data->UserInfo = (userInfo **)realloc(data->UserInfo,++(data->UserInfoLen)*sizeof(userInfo *))))
			perror_exit("%s:%d ",__FILE__,__LINE__);

		/* updateUserList(...) */	
		{
			if(!(data->UserList = (char **)realloc(data->UserList,++(data->UserListLen)*sizeof(char *))))
				perror_exit("%s:%d ",__FILE__,__LINE__);
			data->UserList[data->UserListLen-1] = strdup(users);
		}

		ui->site     = strdup(users);
		ui->referer  = w3lRequest(client,"user_referer(%s)",users);
		ui->entry    = w3lRequest(client,"user_entry_page(%s)",users);
		ui->time     = w3lRequest(client,"user_start_time(%s)",users);
		
		tmp = w3lRequest(client,"user_path_length(%s)",users);
		ui->path     = atoi(tmp);
		free(tmp);
		
		tmp = w3lRequest(client,"user_accesses(%s)",users);
		ui->accesses = atoi(tmp);
		free(tmp);

		data->UserInfo[data->UserInfoLen-1] = ui;
		
		if(*(nl+1) == '\0')
			break;
		users = nl+1;
	}
	free(lunch);
	return;
}


void
updateStats(w3lclient *client,statStorage *data)
{
	updateUserInfo(client,data);
	data->samples++;
}

void
updateInterface_UserInfo(GtkWidget *app, statStorage *data)
{
	int i;
	GtkListStore *listStore;
	GtkTreeIter   iter;

	listStore = (GtkListStore *)gtk_tree_view_get_model(
			(GtkTreeView *)lookup_widget(app,"treeviewUsers"));

	gtk_list_store_clear(listStore);
	for(i=0;i<data->UserInfoLen;i++) {
		gtk_list_store_append(listStore, &iter);
		gtk_list_store_set(listStore, &iter,
			COL_SITE,   (data->UserInfo)[i]->site,
			COL_REF,    (data->UserInfo)[i]->referer,
			COL_ENTRY,  (data->UserInfo)[i]->entry,
			COL_START,  (data->UserInfo)[i]->time,
			COL_PATH,   (data->UserInfo)[i]->path,
			COL_ACC,    (data->UserInfo)[i]->accesses,
			-1);
		free((data->UserInfo)[i]->site);
		free((data->UserInfo)[i]->referer);
		free((data->UserInfo)[i]->entry);
		free((data->UserInfo)[i]->time);
		free((data->UserInfo)[i]);
	}
	if(data->UserInfoLen)
		free(data->UserInfo);
	data->UserInfo = NULL;
	data->UserInfoLen = 0;
}

void
updateInterface_UserList(GtkWidget *app, statStorage *data)
{
	GtkMenu *menu;
	GtkOptionMenu *list;
	GtkMenuItem *menuitem;
	int i = 0;
	
	list = (GtkOptionMenu *)lookup_widget(app,"optionmenuUsers");
	
	menu = (GtkMenu *)gtk_menu_new();
	gtk_widget_set_name ((GtkWidget *)menu, "User List");
	
	menuitem = (GtkMenuItem *)gtk_menu_item_new_with_label(strdup(""));
	gtk_widget_show((GtkWidget *)menuitem);
	gtk_menu_append(menu,(GtkWidget *)menuitem);
	for(i=0;i<data->UserListLen;i++) {
		menuitem = (GtkMenuItem *)gtk_menu_item_new_with_label(strdup(data->UserList[i]));		
		gtk_widget_show((GtkWidget *)menuitem);
		gtk_menu_append(menu,(GtkWidget *)menuitem);
		free(data->UserList[i]);
	}
	free(data->UserList);
	data->UserList = NULL;
	data->UserListLen = 0;

	gtk_option_menu_remove_menu(list);
	gtk_option_menu_set_menu(list,menu);
	
}

void
updateInterface(GtkWidget *app, statStorage *data)
{
	updateInterface_UserInfo(app,data);
	updateInterface_UserList(app,data);
}

void
init_stat_data(statStorage *data)
{
	data->samples = 0;
	data->refreshRate = 8;
	
	data->UserInfo = NULL;
	data->UserInfoLen = 0;
	
	data->UserList = NULL;
	data->UserListLen = 0;

	pthread_mutex_init(&(data->mutex),NULL);
}

void *
thread_update_stats(void *arg)
{
	statStorage *statData;

	GtkWidget *screen;
	GnomeAppBar *status;
	w3lclient *w3lc;

	assert(arg != NULL);

	screen = (GtkWidget *)arg;
	status = (GnomeAppBar *)lookup_widget(screen,"appbarMain");
	w3lc   = (w3lclient *)lookup_widget(screen,"w3lc");

	assert(w3lc != NULL);
	assert(screen != NULL);

	if(!(statData = (statStorage *)malloc(sizeof(statStorage))))
		perror_exit("%s %d",__FILE__,__LINE__);

	init_stat_data(statData);

	while(1) {
		gdk_threads_enter();
		{
			gnome_appbar_push(status,"Updating Statistics");
		}
		gdk_threads_leave();
		
		updateStats(w3lc, statData);
		
		gdk_threads_enter();
		{
			updateInterface(screen, statData);
			gnome_appbar_pop(status);
		}
		gdk_threads_leave();
		updateMonitors(w3lc);

		sleep(statData->refreshRate);
	}
}
